library scrollable_clean_calendar;

import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
import 'package:intl/date_symbol_data_local.dart';
import 'package:scrollable_positioned_list/scrollable_positioned_list.dart';
import 'package:ton_demo/calendar/utils/enums.dart';
import 'package:ton_demo/calendar/widgets/days_widget.dart';
import 'package:ton_demo/calendar/widgets/months_widget.dart';
import 'package:ton_demo/calendar/widgets/title_widget.dart';
import 'package:ton_demo/calendar/widgets/weekdays_widget.dart';
import 'package:ton_demo/calendar/widgets/years_widget.dart';

import 'controllers/clean_calendar_controller.dart';
import 'models/day_values_model.dart';

class ScrollableCleanCalendar extends StatefulWidget {
  /// The language locale
  final String locale;

  /// Scroll controller
  final ScrollController? scrollController;

  /// If is to show or not the weekdays in calendar
  final bool showWeekdays;

  /// The space between month and calendar
  final double spaceBetweenMonthAndCalendar;

  /// The space between calendars
  final double spaceBetweenCalendars;

  /// The horizontal space in the calendar dates
  final double calendarCrossAxisSpacing;

  /// The vertical space in the calendar dates
  final double calendarMainAxisSpacing;

  /// The parent padding
  final EdgeInsets? padding;

  /// The label text style of month
  final TextStyle? monthTextStyle;

  /// The label text align of month
  final TextAlign? monthTextAlign;

  /// The label text align of month
  final TextStyle? weekdayTextStyle;

  /// The aspect ratio of weekday items
  final double? weekdayAspectRatio;

  /// The label text style of day
  final TextStyle? dayTextStyle;

  /// The aspect ratio of day items
  final double? dayAspectRatio;

  /// The day selected background color
  final Color? daySelectedBackgroundColor;

  /// The day background color
  final Color? dayBackgroundColor;

  /// The day selected background color that is between day selected edges
  final Color? daySelectedBackgroundColorBetween;

  /// The day disable background color
  final Color? dayDisableBackgroundColor;

  /// The day disable color
  final Color? dayDisableColor;

  /// The radius of day items
  final double dayRadius;

  /// A builder to make a customized month
  final Widget Function(BuildContext context, String month)? monthBuilder;

  /// A builder to make a customized weekday
  final Widget Function(BuildContext context, String weekday)? weekdayBuilder;

  /// A builder to make a customized day of calendar
  final Widget Function(BuildContext context, DayValues values)? dayBuilder;

  /// The controller of ScrollableCleanCalendar
  final CleanCalendarController calendarController;


  const ScrollableCleanCalendar({
    super.key,
    this.locale = 'en',
    this.scrollController,
    this.showWeekdays = true,
    this.calendarCrossAxisSpacing = 4,
    this.calendarMainAxisSpacing = 4,
    this.spaceBetweenCalendars = 0,
    this.spaceBetweenMonthAndCalendar = 16,
    this.padding,
    this.monthBuilder,
    this.weekdayBuilder,
    this.dayBuilder,
    this.monthTextAlign,
    this.monthTextStyle,
    this.weekdayTextStyle,
    this.weekdayAspectRatio,
    this.daySelectedBackgroundColor,
    this.dayBackgroundColor,
    this.daySelectedBackgroundColorBetween,
    this.dayDisableBackgroundColor,
    this.dayDisableColor,
    this.dayTextStyle,
    this.dayAspectRatio,
    this.dayRadius = 6,
    required this.calendarController,
  });

  @override
  State<ScrollableCleanCalendar> createState() =>
      _ScrollableCleanCalendarState();
}

class _ScrollableCleanCalendarState extends State<ScrollableCleanCalendar> {
  @override
  void initState() {
    initializeDateFormatting();
    WidgetsBinding.instance.addPostFrameCallback((_) {
      final focusDate = widget.calendarController.initialFocusDate;
      if (focusDate != null) {
        widget.calendarController.jumpToMonth(date: focusDate);
      }
    });
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    if (widget.scrollController != null) {
      return listViewCalendar();
    } else {
      return scrollablePositionedListCalendar();
    }
  }

  Widget listViewCalendar() {
    return Column(
      children: [
        Row(
          mainAxisAlignment: MainAxisAlignment.spaceAround,
          children: <Widget>[
            // 居左的按钮
            Padding(
              padding: const EdgeInsets.only(left: 16, top: 16),
              child: GestureDetector(
                onTap: () {
                  widget.calendarController.putSelectTime();
                  Navigator.pop(context);
                },
                child: const Text(
                  '确认',
                  style: TextStyle(color: Colors.lightBlue),
                ),
              ),
            ),
            const Expanded(child: SizedBox()),
            // 居右的按钮
            Padding(
              padding: const EdgeInsets.only(right: 16, top: 16),
              child: GestureDetector(
                onTap: () {
                  Navigator.pop(context);
                },
                child: const Text(
                  '取消',
                  style: TextStyle(color: Colors.lightBlue),
                ),
              ),
            ),
          ],
        ),
        Expanded(
          child: Column(
            children: [
              ListView.separated(
                controller: widget.scrollController,
                separatorBuilder: (_, __) =>
                    SizedBox(height: widget.spaceBetweenCalendars),
                itemCount: widget.calendarController.months.length,
                itemBuilder: (context, index) {
                  final month = widget.calendarController.months[index];
                  return childColumn(month);
                },
              ),
            ],
          ),
        ),
      ],
    );
  }

  Widget scrollablePositionedListCalendar() {
    return Column(
      children: [
        Row(
          mainAxisAlignment: MainAxisAlignment.spaceAround,
          children: <Widget>[
            // 居左的按钮
            Padding(
              padding: const EdgeInsets.only(left: 16, top: 16),
              child: GestureDetector(
                onTap: () {
                  widget.calendarController.putSelectTime();
                  Navigator.pop(context);
                },
                child: const Text(
                  '确认',
                  style: TextStyle(color: Colors.lightBlue),
                ),
              ),
            ),
            const Expanded(child: SizedBox()),
            // 居右的按钮
            Padding(
              padding: const EdgeInsets.only(right: 16, top: 16),
              child: GestureDetector(
                onTap: () {
                  Navigator.pop(context);
                },
                child: const Text(
                  '取消',
                  style: TextStyle(color: Colors.lightBlue),
                ),
              ),
            ),
          ],
        ),
        Expanded(
          child: ScrollablePositionedList.separated(
            itemScrollController:
                widget.calendarController.itemScrollController,
            padding: widget.padding ??
                const EdgeInsets.symmetric(horizontal: 16, vertical: 16),
            separatorBuilder: (_, __) =>
                SizedBox(height: widget.spaceBetweenCalendars),
            itemCount: widget.calendarController.months.length,
            itemBuilder: (context, index) {
              final month = widget.calendarController.months[index];

              return childColumn(month);
            },
          ),
        ),
      ],
    );
  }

  Widget childColumn(DateTime month) {
    return Column(
      crossAxisAlignment: CrossAxisAlignment.start,
      children: [
        if (widget.calendarController.type != ViewType.YEAR)
          SizedBox(
            width: double.maxFinite,
            child: TitleWidget(
              month: month,
              locale: widget.locale,
              monthBuilder: widget.monthBuilder,
              textAlign: widget.monthTextAlign,
              textStyle: widget.monthTextStyle,
              type: widget.calendarController.type,
            ),
          ),
        SizedBox(height: widget.spaceBetweenMonthAndCalendar),
        if (widget.calendarController.type == ViewType.DAY ||
            widget.calendarController.type == ViewType.WEEK)
          Column(
            children: [
              WeekdaysWidget(
                showWeekdays: widget.showWeekdays,
                cleanCalendarController: widget.calendarController,
                locale: widget.locale,
                weekdayBuilder: widget.weekdayBuilder,
                textStyle: widget.weekdayTextStyle,
                aspectRatio: widget.weekdayAspectRatio,
              ),
              AnimatedBuilder(
                animation: widget.calendarController,
                builder: (_, __) {
                  return DaysWidget(
                    month: month,
                    cleanCalendarController: widget.calendarController,
                    calendarCrossAxisSpacing: widget.calendarCrossAxisSpacing,
                    calendarMainAxisSpacing: widget.calendarMainAxisSpacing,
                    dayBuilder: widget.dayBuilder,
                    backgroundColor: widget.dayBackgroundColor,
                    selectedBackgroundColor: widget.daySelectedBackgroundColor,
                    selectedBackgroundColorBetween:
                        widget.daySelectedBackgroundColorBetween,
                    disableBackgroundColor: widget.dayDisableBackgroundColor,
                    dayDisableColor: widget.dayDisableColor,
                    radius: widget.dayRadius,
                    textStyle: widget.dayTextStyle,
                    aspectRatio: widget.dayAspectRatio,
                  );
                },
              )
            ],
          ),
        if (widget.calendarController.type == ViewType.MONTH)
          Column(
            children: [
              AnimatedBuilder(
                animation: widget.calendarController,
                builder: (_, __) {
                  return MonthsWidget(
                    month: month,
                    cleanCalendarController: widget.calendarController,
                    calendarCrossAxisSpacing: widget.calendarCrossAxisSpacing,
                    calendarMainAxisSpacing: widget.calendarMainAxisSpacing,
                    dayBuilder: widget.dayBuilder,
                    backgroundColor: widget.dayBackgroundColor,
                    selectedBackgroundColor: widget.daySelectedBackgroundColor,
                    selectedBackgroundColorBetween:
                        widget.daySelectedBackgroundColorBetween,
                    disableBackgroundColor: widget.dayDisableBackgroundColor,
                    dayDisableColor: widget.dayDisableColor,
                    radius: widget.dayRadius,
                    textStyle: widget.dayTextStyle,
                    aspectRatio: widget.dayAspectRatio,
                  );
                },
              )
            ],
          ),
        if (widget.calendarController.type == ViewType.YEAR)
          Column(
            children: [
              AnimatedBuilder(
                animation: widget.calendarController,
                builder: (_, __) {
                  return YearsWidget(
                    month: month,
                    cleanCalendarController: widget.calendarController,
                    calendarCrossAxisSpacing: widget.calendarCrossAxisSpacing,
                    calendarMainAxisSpacing: widget.calendarMainAxisSpacing,
                    dayBuilder: widget.dayBuilder,
                    backgroundColor: widget.dayBackgroundColor,
                    selectedBackgroundColor: widget.daySelectedBackgroundColor,
                    selectedBackgroundColorBetween:
                        widget.daySelectedBackgroundColorBetween,
                    disableBackgroundColor: widget.dayDisableBackgroundColor,
                    dayDisableColor: widget.dayDisableColor,
                    radius: widget.dayRadius,
                    textStyle: widget.dayTextStyle,
                    aspectRatio: widget.dayAspectRatio,
                  );
                },
              )
            ],
          )
      ],
    );
  }
}
